package wrapper

import (
	"SQLWrapperForGO/config"
	"fmt"
	"strings"
)

/**
 * description：
 * <p>
 * </p>
 * change history:
 * date                      defect#    person       comments
 * -------------------------------------------------------------<p>
 * 2023/9/27 16:24          ********    kong.ruo    create file.
 *
 * @author kong.ruo
 * @date 2023/9/27 16:24
 *
 * @since go 1.20
 */

type UpdateWrapper struct {
	*BasicWrapper
	updateColumns []map[string]interface{}
	action        string
}

func NewUpdateWrapper() *UpdateWrapper {
	return &UpdateWrapper{
		BasicWrapper:  NewBasicWrapper(),
		updateColumns: make([]map[string]interface{}, 0),
	}
}

func (up *UpdateWrapper) Set(column string, value interface{}) *UpdateWrapper {
	info := make(map[string]interface{})
	info[column] = value
	up.updateColumns = append(up.updateColumns, info)
	return up
}

func (up *UpdateWrapper) Update(entity interface{}) *UpdateWrapper {
	fieldMap := GetEntityField(entity)
	for k, v := range fieldMap {
		if config.GetChainResource().Handle(buildChainInParams(k)) {
			//up.action = "ADD"
			continue
		}
		up.Set(k, v)
	}
	return up
}

// Build TODO 根据信息确定是Insert 还是 Update
func (up *UpdateWrapper) Build() string {
	queries := make([]string, 0)

	for _, qc := range up.queries {
		queries = append(queries, buildCondition(qc))
	}
	var cond strings.Builder
	if len(queries) != 0 {
		cond.WriteString(" WHERE ")
		cond.WriteString(joinConditions(queries, " AND "))
	}
	return fmt.Sprintf("UPDATE %s %s%s", up.tableName, formatToSet(up.updateColumns), cond.String())
}

func formatToSet(columns []map[string]interface{}) string {
	cols := make([]string, 0)
	for _, ci := range columns {
		for k, v := range ci {
			cols = append(cols, fmt.Sprintf("SET %s = %v", k, TypeCheck(v)))
		}
	}
	return strings.Join(cols, ",")
}

func buildChainInParams(k string) *config.FilterChainIn {
	return &config.FilterChainIn{
		Mark: config.FilterColumns,
		Key:  k,
	}
}
